package main

import (
	"net"
	"fmt"
	"strings"
)
//定义用户类
type User struct {
	Name string
	Addr string
	C chan string
	conn net.Conn
	server *Server
}
//创建用户对象,当一个连接建立时，表示一个用户上线了
func NewUser(conn net.Conn, server *Server) *User {
	//从这个连接中获取用户的名字和Addr
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:userAddr,
		Addr:userAddr,
		C: make(chan string),
		conn:conn,
		server: server,
	}
	//创建一个协程去监视用户的channel
	go user.ListenM()
	return user
}

//监听当前用户的channel，一旦有消息，立马发给客户端
func (this *User) ListenM(){
	for {
		msg := <-this.C
		this.conn.Write([]byte(msg+"\n"))
	}
}

//用户上线
func (this *User) OnLine(){
	//用户上线后，要广播告知其他用户,即将这个消息放入到消息队列中
	this.server.BroadCast(this,"Online......")
	//把用户放在在线用户列表中
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()
}
//用户下线
func (this *User) OffLine(){
	//用户下线后，要广播告知其他用户,即将这个消息放入到消息队列中
	this.server.BroadCast(this,"OffLine......")
	//把用户在在线用户列表中删除
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap,this.Name)
	this.server.mapLock.Unlock()
}

//将在线成员列表发送给查询用户的客户端
func (this *User) SendCli(str string){
	this.conn.Write([]byte(str))
}

//用户发送消息
func (this *User) DoMessage(msg string){
	//用户输入指令查询当前在线用户
	if msg == "who" {
		this.server.mapLock.Lock()
		for _,u := range this.server.OnlineMap{
			sendMessage := "["+u.Name+"]"+"Online......\n"
			this.SendCli(sendMessage)
		}
		this.server.mapLock.Unlock()
	}else if len(msg) >7 && msg[:7] == "rename|" {
		//允许用户修改自己的用户名，消息格式为rename|张三
		NewName := msg[7:]
		//访问在线用户列表，查询名字是否被占用，如果没有，就修改用户名
		//加锁
		this.server.mapLock.Lock()
		//判断是否占用
		_, err := this.server.OnlineMap[NewName]
		if err {
			fmt.Println("该昵称已被占用")
			this.SendCli("该昵称已被占用")
		}else{
			//未被占用，修改
			delete(this.server.OnlineMap,this.Name)
			this.server.OnlineMap[NewName] = this
			this.Name = NewName
			fmt.Println("新用户名"+this.Name+"已修改...\n")
			this.SendCli("新用户名"+this.Name+"已修改...\n")
		}
		this.server.mapLock.Unlock()
	}else if len(msg)>4 && msg[:3] == "to|" {
		//允许用户之间私聊，消息格式为to|ymiir|Hello
		//首先获取目的用户名
		remoteName := strings.Split(msg,"|")[1]
		//判断用户名是否为空
		if remoteName == "" {
			this.SendCli("用户名为空,请按格式发送信息to|ymiir|Hello\n")
			return
		}
		//获取消息
		toMsg := strings.Split(msg,"|")[2]
		if toMsg == ""{
			this.SendCli("消息为空，请填入消息\n")
			return
		}
		//找到用户
		remoteUser, ok := this.server.OnlineMap[remoteName]
		//判断用户是否在线
		if !ok {
			this.SendCli("没有找到这个用户\n")
			return
		}else{
			remoteUser.SendCli("["+this.Name+"]"+"给您发送:"+toMsg)
			this.SendCli("发送成功")
		}
	}else {
		this.server.BroadCast(this,msg)
	}
}